#ifndef _H_C_SERVICE_H_
#define _H_C_SERVICE_H_

#include "IService.h"
#include "ServiceDelegate.h"
#include "IServiceBackend.h"

namespace QWER
{
	QTEMPLATE<typename FRONTEND> QWHERE(FRONTEND: IServiceFrontend)
	QDLL_EXPORT QCLASS CService : public IService
	{
	public:
		VAL_OR_PTR(FRONTEND) Connect(PTR_OR_REF(CServiceFrontendHelper) roHelper)
		{
			return (VAL_OR_PTR(FRONTEND)) _Connect(roHelper, 
				NEW_DELEGATE(
					QPACK(DNewServiceFrontend<IServiceFrontend>),
					this, CService<FRONTEND>::_NewFrontend,
					DELEGATE_PLACEHOLDERS(, std::placeholders::_1)
				)
			);
		}

		VAL_OR_PTR(FRONTEND) Connect(PTR_OR_REF(CServiceBackendHelper) roHelper)
		{
			return (VAL_OR_PTR(FRONTEND)) _Connect(roHelper,
				NEW_DELEGATE(
					QPACK(DNewServiceFrontend<IServiceFrontend>),
					this, CService<FRONTEND>::_NewFrontend,
					DELEGATE_PLACEHOLDERS(, std::placeholders::_1)
				)
			);
		}

		VAL_OR_PTR(FRONTEND) Connect(PTR_OR_REF(CApplicationHelper) roHelper)
		{
			return (VAL_OR_PTR(FRONTEND)) _Connect(roHelper,
				NEW_DELEGATE(
					QPACK(DNewServiceFrontend<IServiceFrontend>),
					this, CService<FRONTEND>::_NewFrontend,
					DELEGATE_PLACEHOLDERS(, std::placeholders::_1)
				)
			);
		}

	private:
		CUniquePtr(IServiceFrontend) _NewFrontend(PTR(IService) poThisService)
		{
			return QMOVE(CUniquePtr(IServiceFrontend)(QReleaseFromUniquePtr(m_cbNewFrontend(poThisService))));
		}

	private:
		PTR_OR_VAL(DNewServiceFrontend<FRONTEND>) m_cbNewFrontend;

#ifdef _USING_CLI
	internal:
#else
	private:
        friend class IRunner;
#endif
		CService(CONST_PTR_OR_REF(DNewServiceFrontend<FRONTEND>) cbNewFrontend, CMPSCQueue<IServiceMsg*>& roPipe):
			IService(roPipe), m_cbNewFrontend(cbNewFrontend)
		{
		}
	};
}

#endif
